# AIQuant 生产环境配置
# 高性能、高可用性、安全性配置

import os
from typing import List, Optional
from pydantic import BaseSettings, validator
from datetime import timedelta

class ProductionSettings(BaseSettings):
    """生产环境配置类"""
    
    # =============================================================================
    # 基础配置
    # =============================================================================
    ENVIRONMENT: str = "production"
    DEBUG: bool = False
    TESTING: bool = False
    
    # 应用信息
    APP_NAME: str = "AIQuant"
    APP_VERSION: str = "1.0.0"
    APP_DESCRIPTION: str = "AI-powered Quantitative Investment Research System"
    
    # =============================================================================
    # 服务器配置
    # =============================================================================
    # API服务器
    API_HOST: str = "0.0.0.0"
    API_PORT: int = 8000
    API_WORKERS: int = 4
    API_WORKER_CLASS: str = "uvicorn.workers.UvicornWorker"
    API_WORKER_CONNECTIONS: int = 1000
    API_MAX_REQUESTS: int = 10000
    API_MAX_REQUESTS_JITTER: int = 1000
    API_TIMEOUT: int = 300
    API_KEEPALIVE: int = 5
    
    # Web仪表板
    WEB_HOST: str = "0.0.0.0"
    WEB_PORT: int = 8501
    WEB_SERVER_HEADLESS: bool = True
    WEB_SERVER_ENABLE_CORS: bool = False
    WEB_SERVER_ENABLE_XSRF_PROTECTION: bool = True
    
    # =============================================================================
    # 数据库配置
    # =============================================================================
    # PostgreSQL主库
    DATABASE_URL: str
    DATABASE_POOL_SIZE: int = 20
    DATABASE_MAX_OVERFLOW: int = 30
    DATABASE_POOL_TIMEOUT: int = 30
    DATABASE_POOL_RECYCLE: int = 3600
    DATABASE_POOL_PRE_PING: bool = True
    DATABASE_ECHO: bool = False
    DATABASE_ECHO_POOL: bool = False
    
    # 数据库连接重试
    DATABASE_RETRY_ATTEMPTS: int = 5
    DATABASE_RETRY_DELAY: int = 5
    
    # 时间序列数据库
    TIMESCALE_CHUNK_TIME_INTERVAL: str = "1 day"
    TIMESCALE_COMPRESSION_ENABLED: bool = True
    TIMESCALE_COMPRESSION_AFTER: str = "7 days"
    
    # =============================================================================
    # Redis配置
    # =============================================================================
    REDIS_URL: str
    REDIS_POOL_SIZE: int = 50
    REDIS_POOL_MAX_CONNECTIONS: int = 100
    REDIS_SOCKET_TIMEOUT: int = 5
    REDIS_SOCKET_CONNECT_TIMEOUT: int = 5
    REDIS_SOCKET_KEEPALIVE: bool = True
    REDIS_SOCKET_KEEPALIVE_OPTIONS: dict = {}
    REDIS_HEALTH_CHECK_INTERVAL: int = 30
    
    # Redis集群配置
    REDIS_CLUSTER_ENABLED: bool = False
    REDIS_SENTINEL_ENABLED: bool = False
    REDIS_SENTINEL_HOSTS: List[str] = []
    REDIS_SENTINEL_SERVICE_NAME: str = "mymaster"
    
    # =============================================================================
    # Celery配置
    # =============================================================================
    CELERY_BROKER_URL: str
    CELERY_RESULT_BACKEND: str
    CELERY_TASK_SERIALIZER: str = "json"
    CELERY_RESULT_SERIALIZER: str = "json"
    CELERY_ACCEPT_CONTENT: List[str] = ["json"]
    CELERY_TIMEZONE: str = "Asia/Shanghai"
    CELERY_ENABLE_UTC: bool = True
    
    # Worker配置
    CELERY_WORKER_CONCURRENCY: int = 4
    CELERY_WORKER_PREFETCH_MULTIPLIER: int = 1
    CELERY_WORKER_MAX_TASKS_PER_CHILD: int = 1000
    CELERY_WORKER_DISABLE_RATE_LIMITS: bool = False
    
    # 任务配置
    CELERY_TASK_SOFT_TIME_LIMIT: int = 300
    CELERY_TASK_TIME_LIMIT: int = 600
    CELERY_TASK_ACKS_LATE: bool = True
    CELERY_TASK_REJECT_ON_WORKER_LOST: bool = True
    CELERY_TASK_IGNORE_RESULT: bool = False
    
    # 结果后端配置
    CELERY_RESULT_EXPIRES: int = 3600
    CELERY_RESULT_PERSISTENT: bool = True
    CELERY_RESULT_COMPRESSION: str = "gzip"
    
    # Beat调度器配置
    CELERY_BEAT_SCHEDULE: dict = {
        'market-data-sync': {
            'task': 'aiquant.tasks.sync_market_data',
            'schedule': 60.0,  # 每分钟
        },
        'portfolio-rebalance': {
            'task': 'aiquant.tasks.rebalance_portfolio',
            'schedule': 3600.0,  # 每小时
        },
        'risk-monitoring': {
            'task': 'aiquant.tasks.monitor_risk',
            'schedule': 300.0,  # 每5分钟
        },
        'system-health-check': {
            'task': 'aiquant.tasks.health_check',
            'schedule': 120.0,  # 每2分钟
        },
        'data-cleanup': {
            'task': 'aiquant.tasks.cleanup_old_data',
            'schedule': 86400.0,  # 每天
        },
    }
    
    # =============================================================================
    # 安全配置
    # =============================================================================
    SECRET_KEY: str
    JWT_SECRET_KEY: str
    JWT_ALGORITHM: str = "HS256"
    JWT_ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
    JWT_REFRESH_TOKEN_EXPIRE_DAYS: int = 7
    
    # CORS配置
    CORS_ORIGINS: List[str] = []
    CORS_ALLOW_CREDENTIALS: bool = True
    CORS_ALLOW_METHODS: List[str] = ["GET", "POST", "PUT", "DELETE"]
    CORS_ALLOW_HEADERS: List[str] = ["*"]
    
    # 速率限制
    RATE_LIMIT_ENABLED: bool = True
    RATE_LIMIT_REQUESTS_PER_MINUTE: int = 100
    RATE_LIMIT_BURST: int = 200
    
    # SSL/TLS配置
    SSL_ENABLED: bool = True
    SSL_CERT_PATH: Optional[str] = None
    SSL_KEY_PATH: Optional[str] = None
    SSL_CA_CERTS: Optional[str] = None
    
    # =============================================================================
    # 日志配置
    # =============================================================================
    LOG_LEVEL: str = "INFO"
    LOG_FORMAT: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    LOG_DATE_FORMAT: str = "%Y-%m-%d %H:%M:%S"
    
    # 日志文件配置
    LOG_FILE_ENABLED: bool = True
    LOG_FILE_PATH: str = "logs/aiquant.log"
    LOG_FILE_MAX_SIZE: int = 100 * 1024 * 1024  # 100MB
    LOG_FILE_BACKUP_COUNT: int = 10
    LOG_FILE_ROTATION: str = "midnight"
    
    # 结构化日志
    LOG_JSON_FORMAT: bool = True
    LOG_INCLUDE_TRACE_ID: bool = True
    
    # 外部日志服务
    LOG_ELASTICSEARCH_ENABLED: bool = True
    LOG_ELASTICSEARCH_HOST: str = "elasticsearch:9200"
    LOG_ELASTICSEARCH_INDEX: str = "aiquant-logs"
    
    # =============================================================================
    # 监控配置
    # =============================================================================
    # Prometheus指标
    METRICS_ENABLED: bool = True
    METRICS_PORT: int = 9090
    METRICS_PATH: str = "/metrics"
    
    # 健康检查
    HEALTH_CHECK_ENABLED: bool = True
    HEALTH_CHECK_PATH: str = "/health"
    HEALTH_CHECK_TIMEOUT: int = 30
    
    # 性能监控
    PERFORMANCE_MONITORING_ENABLED: bool = True
    SLOW_QUERY_THRESHOLD: float = 1.0  # 秒
    SLOW_REQUEST_THRESHOLD: float = 2.0  # 秒
    
    # APM配置
    APM_ENABLED: bool = False
    APM_SERVICE_NAME: str = "aiquant-api"
    APM_SERVER_URL: Optional[str] = None
    APM_SECRET_TOKEN: Optional[str] = None
    
    # =============================================================================
    # 缓存配置
    # =============================================================================
    CACHE_ENABLED: bool = True
    CACHE_DEFAULT_TIMEOUT: int = 300  # 5分钟
    CACHE_KEY_PREFIX: str = "aiquant:"
    
    # 缓存策略
    CACHE_MARKET_DATA_TIMEOUT: int = 60  # 1分钟
    CACHE_USER_SESSION_TIMEOUT: int = 1800  # 30分钟
    CACHE_API_RESPONSE_TIMEOUT: int = 300  # 5分钟
    
    # =============================================================================
    # 业务配置
    # =============================================================================
    # 市场数据
    MARKET_DATA_PROVIDERS: List[str] = ["tushare", "akshare", "yfinance"]
    MARKET_DATA_UPDATE_INTERVAL: int = 60  # 秒
    MARKET_DATA_RETENTION_DAYS: int = 365
    
    # 交易配置
    TRADING_ENABLED: bool = False  # 生产环境默认关闭实盘交易
    TRADING_MODE: str = "simulation"  # simulation, paper, live
    TRADING_COMMISSION_RATE: float = 0.0003
    TRADING_SLIPPAGE_RATE: float = 0.0001
    
    # 风险管理
    RISK_MONITORING_ENABLED: bool = True
    MAX_POSITION_SIZE: float = 0.1  # 10%
    MAX_DAILY_LOSS: float = 0.05  # 5%
    STOP_LOSS_THRESHOLD: float = 0.02  # 2%
    
    # 智能体配置
    AGENT_MAX_CONCURRENT: int = 10
    AGENT_TIMEOUT: int = 300
    AGENT_RETRY_ATTEMPTS: int = 3
    
    # =============================================================================
    # 外部服务配置
    # =============================================================================
    # 邮件服务
    EMAIL_ENABLED: bool = True
    SMTP_HOST: str = "smtp.gmail.com"
    SMTP_PORT: int = 587
    SMTP_USE_TLS: bool = True
    SMTP_USERNAME: Optional[str] = None
    SMTP_PASSWORD: Optional[str] = None
    
    # 消息通知
    NOTIFICATION_ENABLED: bool = True
    NOTIFICATION_CHANNELS: List[str] = ["email", "webhook"]
    WEBHOOK_URL: Optional[str] = None
    
    # 第三方API
    OPENAI_API_KEY: Optional[str] = None
    OPENAI_MODEL: str = "gpt-4"
    OPENAI_MAX_TOKENS: int = 4000
    OPENAI_TEMPERATURE: float = 0.1
    
    # =============================================================================
    # 性能优化配置
    # =============================================================================
    # 数据库查询优化
    DATABASE_QUERY_CACHE_ENABLED: bool = True
    DATABASE_QUERY_CACHE_SIZE: int = 1000
    DATABASE_SLOW_QUERY_LOG: bool = True
    
    # 异步处理
    ASYNC_POOL_SIZE: int = 100
    ASYNC_TIMEOUT: int = 30
    
    # 内存管理
    MEMORY_LIMIT_MB: int = 2048
    MEMORY_WARNING_THRESHOLD: float = 0.8
    
    # =============================================================================
    # 备份和恢复
    # =============================================================================
    BACKUP_ENABLED: bool = True
    BACKUP_SCHEDULE: str = "0 2 * * *"  # 每天凌晨2点
    BACKUP_RETENTION_DAYS: int = 30
    BACKUP_STORAGE_PATH: str = "/backups"
    
    # 云存储备份
    CLOUD_BACKUP_ENABLED: bool = False
    CLOUD_BACKUP_PROVIDER: str = "s3"  # s3, gcs, azure
    CLOUD_BACKUP_BUCKET: Optional[str] = None
    CLOUD_BACKUP_ACCESS_KEY: Optional[str] = None
    CLOUD_BACKUP_SECRET_KEY: Optional[str] = None
    
    # =============================================================================
    # 验证器
    # =============================================================================
    @validator('DATABASE_URL')
    def validate_database_url(cls, v):
        if not v or not v.startswith('postgresql://'):
            raise ValueError('DATABASE_URL must be a valid PostgreSQL URL')
        return v
    
    @validator('REDIS_URL')
    def validate_redis_url(cls, v):
        if not v or not v.startswith('redis://'):
            raise ValueError('REDIS_URL must be a valid Redis URL')
        return v
    
    @validator('SECRET_KEY', 'JWT_SECRET_KEY')
    def validate_secret_keys(cls, v):
        if not v or len(v) < 32:
            raise ValueError('Secret keys must be at least 32 characters long')
        return v
    
    @validator('LOG_LEVEL')
    def validate_log_level(cls, v):
        valid_levels = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
        if v.upper() not in valid_levels:
            raise ValueError(f'LOG_LEVEL must be one of {valid_levels}')
        return v.upper()
    
    class Config:
        env_file = ".env.production"
        env_file_encoding = "utf-8"
        case_sensitive = True
        
        # 环境变量前缀
        env_prefix = "AIQUANT_"
        
        # 字段别名
        fields = {
            'DATABASE_URL': {'env': ['DATABASE_URL', 'POSTGRES_URL']},
            'REDIS_URL': {'env': ['REDIS_URL', 'CACHE_URL']},
            'SECRET_KEY': {'env': ['SECRET_KEY', 'APP_SECRET']},
        }

# 创建配置实例
settings = ProductionSettings()

# 导出常用配置
__all__ = ['settings', 'ProductionSettings']